package com.pan.admin.module.api.service.impl;

import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.base.MapUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.pan.admin.module.api.dao.ApiKeyHistoryBillDao;
import com.pan.admin.module.api.entity.qo.ApiKeyHistoryBillQO;
import com.pan.admin.module.api.entity.vo.ApiKeyBillVO;
import com.pan.admin.module.api.entity.vo.ApiKeyHistoryBillDetailVO;
import com.pan.admin.module.api.entity.vo.ApiKeyHistoryBillVO;
import com.pan.admin.module.api.enums.ApiKeyBillTypeEnum;
import com.pan.admin.module.api.service.ApiKeyHistoryBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

@Service
public class ApiKeyHistoryBillServiceImpl implements ApiKeyHistoryBillService {

    @Autowired
    private ApiKeyHistoryBillDao apiKeyHistoryBillDao;

    @Override
    @Transactional(readOnly = true)
    public List<ApiKeyHistoryBillVO> list(ApiKeyHistoryBillQO apiKeyHistoryBillQO, String displayDateTime) {

        // api渠道
        List<ApiKeyHistoryBillVO> apiKeyList = this.apiKeyHistoryBillDao.listApiKey(apiKeyHistoryBillQO);

        //  结余
        List<ApiKeyHistoryBillVO> apiHistoryBillVOS = this.apiKeyHistoryBillDao.listApiKeySurplusBill(apiKeyHistoryBillQO);

        // 机构总消耗
        List<ApiKeyHistoryBillVO> listLoanProductTotalConsumption = this.apiKeyHistoryBillDao.listLoanProductTotalConsumption(apiKeyHistoryBillQO);

        Map<String, BigDecimal> loanProductConsumeMap = listLoanProductTotalConsumption.stream()
            .collect(Collectors.toMap(ApiKeyHistoryBillVO::getApiClientId, ApiKeyHistoryBillVO::getAmount));

        // 将结余数据按 loanProductId 存储在 Map 中
        Map<String, BigDecimal> surplusMap = apiHistoryBillVOS.stream()
            .filter(loanProduct -> loanProduct.getApiClientId() != null)
            .filter(loanProduct -> loanProduct.getAccountBalance() != null)
        .collect(Collectors.toMap(ApiKeyHistoryBillVO::getApiClientId, ApiKeyHistoryBillVO::getAccountBalance));

        // 将结余价格赋值给对应的计划项
        apiKeyList.forEach(item ->{
            BigDecimal accountBalance = surplusMap.get(item.getApiClientId());
            if (accountBalance != null) {
                item.setAccountBalance(accountBalance);
            }
        });

        // 账单
        List<ApiKeyBillVO> apiKeyBill = this.apiKeyHistoryBillDao.listApiKeyBill(apiKeyHistoryBillQO);

        // 充值
        Map<String, BigDecimal> rechargeMap = apiKeyBill.stream()
            .filter(item -> Eq.object(item.getType(), ApiKeyBillTypeEnum.RECHARGE.getValue()))
        .collect(Collectors.toMap(ApiKeyBillVO::getApiClientId, ApiKeyBillVO::getAmount));
        // 补单
        Map<String, BigDecimal> supplementMap = apiKeyBill.stream()
            .filter(item -> Eq.object(item.getType(), ApiKeyBillTypeEnum.SUPPLEMENT.getValue()))
        .collect(Collectors.toMap(ApiKeyBillVO::getApiClientId, ApiKeyBillVO::getAmount));

        // 账单按主体id分组
        Map<String, List<ApiKeyBillVO>> groupMap = apiKeyBill.stream()
            .filter(apiKey -> apiKey.getApiClientId() != null)
        .collect(Collectors.groupingBy(ApiKeyBillVO::getApiClientId));

        apiKeyList.forEach(apiKey -> {
            // 在分组中获取当前主体的账单
            List<ApiKeyBillVO> currentBill = groupMap.get(apiKey.getApiClientId());
            // 验证非空
            if (ValidParam.isEmpty(currentBill)) {
                return;
            }
            currentBill.forEach(bill -> {
                // 机构计划
                if (Objects.equals(bill.getType(), ApiKeyBillTypeEnum.ORG_PLAN.getValue())) {
                    apiKey.addTotal(bill.getTotal());
                    apiKey.addAmount(bill.getAmount());
                    apiKey.addNormal(bill.getTotal());
                    // plan.addWake(bill.getTotal());
                }
                // 平台计划
                if (Objects.equals(bill.getType(), ApiKeyBillTypeEnum.PLATFORM_PLAN.getValue())) {
                    apiKey.addTotal(bill.getTotal());
                    apiKey.addAmount(bill.getAmount());
                    apiKey.addNormal(bill.getTotal());
                    // plan.addWake(bill.getTotal());
                }
                // 唤醒计划
                if (Objects.equals(bill.getType(), ApiKeyBillTypeEnum.WAKE.getValue())) {
                    apiKey.addTotal(bill.getTotal());
                    apiKey.addAmount(bill.getAmount());
                    // plan.addNormal(bill.getTotal());
                    apiKey.addWake(bill.getTotal());
                }
            });
        });

        apiKeyList.forEach(item -> {
            // 空值处理
            if (item.getAmount() == null) {
                item.setAmount(BigDecimal.ZERO);
            }
            // 渠道总消耗
            BigDecimal apiConsume = item.getAmount();
            // 机构总消耗
            BigDecimal loanProductConsume = loanProductConsumeMap.getOrDefault(item.getApiClientId(), BigDecimal.ZERO);
            // 渠道总充值
            BigDecimal apiRecharge = rechargeMap.getOrDefault(item.getApiClientId(), BigDecimal.ZERO);
            // 渠道总补单
            BigDecimal apiSupplement = supplementMap.getOrDefault(item.getApiClientId(), BigDecimal.ZERO);
            // 利润 = 机构总消耗-渠道总消耗
            BigDecimal profit = loanProductConsume.subtract(apiConsume);

            item.addRecharge(apiRecharge);
            item.addSupplement(apiSupplement);
            item.setProfit(profit);
        });

        // 分组
        Map<String, List<ApiKeyHistoryBillVO>> groupedMap = apiKeyList.stream()
                .filter(apiKey -> apiKey.getGroupingWords() != null)
                .collect(Collectors.groupingBy(ApiKeyHistoryBillVO::getGroupingWords));

        // 转换为ApiKeyHistoryBillVO列表
        List<ApiKeyHistoryBillVO> groupedResult = groupedMap.entrySet().stream()
                .map(entry -> {
                    ApiKeyHistoryBillVO groupingWordsVO = new ApiKeyHistoryBillVO();
                    groupingWordsVO.setGroupingWords(entry.getKey());
                    groupingWordsVO.setChildren(entry.getValue());
                    for (ApiKeyHistoryBillVO apiKey : entry.getValue()) {
                        groupingWordsVO.addTotal(apiKey.getTotal());
                        groupingWordsVO.addAmount(apiKey.getAmount());
                        groupingWordsVO.addRecharge(apiKey.getRecharge());
                        groupingWordsVO.addSupplement(apiKey.getSupplement());
                        groupingWordsVO.addProfit(apiKey.getProfit());
                        groupingWordsVO.addNormal(apiKey.getNormal());
                        groupingWordsVO.addWake(apiKey.getWake());
                        groupingWordsVO.addBalance(apiKey.getBalance());
                        groupingWordsVO.addAccountBalance(apiKey.getAccountBalance());
                    }
                    return groupingWordsVO;
                })
                .collect(Collectors.toList());

        AtomicLong index = new AtomicLong(1l);
        groupedResult.forEach(item -> {
            item.setId(index.getAndIncrement());
            item.getChildren().forEach(item2 ->{
                item2.setId(index.getAndIncrement());
            });
        });

        //  排序
        Map<String, Comparator<ApiKeyHistoryBillVO>> comparatorMap = MapUtils.newLinkedHashMap(map -> {
            map.put("total", Comparator.nullsFirst(Comparator.comparing(ApiKeyHistoryBillVO::getTotal)));
            map.put("amount", Comparator.nullsFirst(Comparator.comparing(ApiKeyHistoryBillVO::getAmount)));
            map.put("wake", Comparator.nullsFirst(Comparator.comparing(ApiKeyHistoryBillVO::getWake)));
            map.put("normal", Comparator.nullsFirst(Comparator.comparing(ApiKeyHistoryBillVO::getNormal)));
            map.put("recharge", Comparator.nullsFirst(Comparator.comparing(ApiKeyHistoryBillVO::getRecharge)));
            map.put("supplement", Comparator.nullsFirst(Comparator.comparing(ApiKeyHistoryBillVO::getSupplement)));
            map.put("profit", Comparator.nullsFirst(Comparator.comparing(ApiKeyHistoryBillVO::getProfit)));
        });

        Comparator<ApiKeyHistoryBillVO> comparator = comparatorMap.get(apiKeyHistoryBillQO.getSortField());
        if (comparator == null) {
            comparator = comparatorMap.get("total");
        }
        if (!Eq.str(apiKeyHistoryBillQO.getSort(), "ascending")) {
            comparator = comparator.reversed();
        }

        Comparator<ApiKeyHistoryBillVO> comparator2 = comparator;
        // 将数据进行排序
        groupedResult.sort(comparator2);
        groupedResult.forEach(item -> item.getChildren().sort(comparator2));

        //  通一设置截止时间
        groupedResult.forEach(item -> {
            item.setDateTime(displayDateTime);
            item.getChildren().forEach(item2 -> item2.setDateTime(displayDateTime));
        });

        //  通一设置界面中每一级所展示的数据
        groupedResult.forEach(item -> {
            item.getChildren().forEach(item2 -> item2.setGroupingWords(null));
        });
        return groupedResult;
    }

    @Override
    @Transactional(readOnly = true)
    public List<ApiKeyHistoryBillDetailVO> getBillDetail(ApiKeyHistoryBillQO apiKeyHistoryBillQO) {
        return apiKeyHistoryBillDao.getBillDetail(apiKeyHistoryBillQO);
    }
}
